// Map.h
//
//  Created on: Oct 11, 2012
//      Author: travis
//
//	Main map class

#pragma once

#include "ShaderPool.h"

#ifdef _WIN32 
#include <windows.h> 
#include "SDL_thread.h"
#else
#include "SDL/SDL_thread.h"
#endif

#include <iostream>
#include <string.h>

#include "Terrain.h"
#include "Water.h"
#include "Sky.h"

#include "TexPool.h"
#include "models/ModelPool.h"

#include "objects/Objects.h"

#include <vector>
#include <time.h>
#include "effects/glShadow.h"
#include "effects/glReflection.h"
#include "effects/glRefraction.h"

#include "scene/Camera.h"
#include "scene/Cursor.h"
#include <glm/glm.hpp>
#include "scene/World.h"
#include "scene/Timer.h"

#include "mechanics/PathFinder.h"
#include "octree/Box.h"
#include <math.h>
#include "threads/ThrPool.h"
#include "engine/RTSException.h"

#define CULLING_DIV 5

namespace Map
{

class Box;

class Map
{
public:
	Map(Timer *_fps);
	virtual ~Map();

	void clearMap();
	int getSize();
	void setSize(int s);
	std::string getName();
	void setName(std::string N);
	void generateMap();
	//-------------------------------------------------------------------------

	// draw section
	void drawAll();

	// control section
	// called from thread in RTS!!!!
	void control(SDL_Event *event, float t);
	//-------------------------------------------------------------------------

	// show/hide section
	void showWater();
	void hideWater();

	void showSky();
	void hideSky();
	void showTerrain();
	void hideTerrain();
	void showAll();
	void hideAll();
	void showEntities();
	void hideEntities();
	bool isWaterVisible();
	bool isTerrainVisible();
	bool areEntitiesVisible();
	//-------------------------------------------------------------------------

	// get/set section
	ModelPool*& getPool();
	void setPool(ModelPool*& pool);
	PathFinder*& getPathfinder();
	void setPathfinder(PathFinder*& pathfinder);
	glReflection*& getReflection();
	void setReflection(glReflection*& reflection);
	glRefraction*& getRefraction();
	void setRefraction(glRefraction*& refraction);
	glShadow*& getShadows();
	void setShadows(glShadow*& shadows);
	Sky*& getSky();
	void setSky(Sky*& sky);
	Terrain::Terrain*& getTer();
	void setTer(Terrain::Terrain*& ter);
	Water*& getWater();
	void setWater(Water*& water);
	RTSCursor::Cursor*& getCursor();
	void setCursor(RTSCursor::Cursor*& cursor);
	bool isBoxVisible() const;
	void setBoxVisible(bool boxVisible);
	Octree::Box*& getOctree();
	void setOctree(Octree::Box*& octree);
	bool isOctreeBox();
	void setOctreeBox(bool octreeBox);

	Objects::Objects* getEntities();

private:
	Octree::Box *OcMainBox;
	RTSCursor::Cursor *cursor;
	Terrain::Terrain *ter; // terrain object
	Water *water; // water object
	ModelPool *mPool; // model pool for storing and loading models
	glShadow *shadows; // creating shadow map
	glReflection *reflection; // creatig reflection texture for water
	glRefraction *refraction; // create refraction texture unit
	Sky *sky; // epic blue sky
	PathFinder *pathfinder; // Brutal algorithm for finding a best path ever
	Objects::Objects *entities;

	int MapSize;
	std::string Name;

	Timer *fps;
	// visible
	bool terVisible, watVisible, entVisible, skyVisible, bBoxVisible, octreeBox;
	// visible
	// -----------------------------------------
};
}

